//
// Created by user on 20-3-14.
//
#include "Gate.h"
#include "../ProcessManagement/Task.h"

extern Tss initTss[NR_CPUS];

inline void set_intr_gate(unsigned int n, unsigned char ist, void *addr) {
    _set_gate(IDT_TABLE + n, 0x8E, ist, 0x8 << 16, addr);    //P=1, DPL=0, TYPE=E
}

inline void set_trap_gate(unsigned int n, unsigned char ist, void *addr) {
    _set_gate(IDT_TABLE + n, 0x8F, ist, 0x8 << 16, addr);    //P=1, DPL=0, TYPE=F
}

inline void set_system_gate(unsigned int n, unsigned char ist, void *addr) {
    _set_gate(IDT_TABLE + n, 0xEF, ist, 0x8 << 16, addr);    //P=1, DPL=3, TYPE=F
}

inline void set_reserve_gate(unsigned int n, unsigned char ist, void *addr) {
    _set_gate(IDT_TABLE + n, 0x00, ist, 0,addr);    //P=1, DPL=3, TYPE=F
}

inline void setTSSDescriptor(unsigned int n, void *addr) {

    unsigned long limit = 103;
    *(unsigned long *) (GDT_TABLE + n) =
            (limit & 0xffff) | (((unsigned long) addr & 0xffff) << 16) | (((unsigned long) addr >> 16 & 0xff) << 32) |
            ((unsigned long) 0x89 << 40) | ((limit >> 16 & 0xf) << 48) |
            (((unsigned long) addr >> 24 & 0xff) << 56);    /////89 is attribute
    *(unsigned long *) (GDT_TABLE + n + 1) = ((unsigned long) addr >> 32 & 0xffffffff) | 0;

}

void setTSS64(unsigned long rsp0, unsigned long rsp1, unsigned long rsp2, unsigned long ist1, unsigned long ist2,
              unsigned long ist3,
              unsigned long ist4, unsigned long ist5, unsigned long ist6, unsigned long ist7) {
    *(unsigned long *) (initTss + 1) = rsp0;
    *(unsigned long *) (initTss + 3) = rsp1;
    *(unsigned long *) (initTss + 5) = rsp2;

    *(unsigned long *) (initTss + 9) = ist1;
    *(unsigned long *) (initTss + 11) = ist2;
    *(unsigned long *) (initTss + 13) = ist3;
    *(unsigned long *) (initTss + 15) = ist4;
    *(unsigned long *) (initTss + 17) = ist5;
    *(unsigned long *) (initTss + 19) = ist6;
    *(unsigned long *) (initTss + 21) = ist7;
}
